#include "sdk.h"
#include "multiselectdlg.h"

BEGIN_EVENT_TABLE( MultiSelectDlg, wxScrollingDialog )
  EVT_CHECKLISTBOX( XRCID( "lstItems" ), MultiSelectDlg::OnItemToggle )
  EVT_BUTTON( XRCID( "btnSelectWild" ), MultiSelectDlg::OnWildcard )
  EVT_BUTTON( XRCID( "btnToggle" ), MultiSelectDlg::OnToggle )
  EVT_BUTTON( XRCID( "btnSelectAll" ), MultiSelectDlg::OnSelectAll )
  EVT_BUTTON( XRCID( "btnDeselectAll" ), MultiSelectDlg::OnDeselectAll )
END_EVENT_TABLE()

MultiSelectDlg::MultiSelectDlg( wxWindow* parent, const wxArrayString& items, const wxString& wildcard, const wxString& label, const wxString& title ) {
  wxXmlResource* xml_res = wxXmlResource::Get();
  wxString resPath = ConfigManager::GetDataFolder() + _T( "/generic_multi_select.xrc" ) ;
  if( !xml_res->Load( resPath ) )  {
    xml_File_lock = false;
    Manager::Get()->GetLogManager()->LogInf( F( _T( "文件丢失: %s " ), resPath.wx_str() ) );
    return;
  }
  if( !xml_res->LoadObject( this, parent, _T( "dlgGenericMultiSelect" ), _T( "wxScrollingDialog" ) ) ) {
    xml_File_lock = false;
    Manager::Get()->GetLogManager()->LogInf( _T( "资源丢失" ) );
    return;
  }
  xml_File_lock = true;
  XRCCTRL( *this, "wxID_OK", wxButton )->SetDefault();
  SetTitle( title );
  XRCCTRL( *this, "lblLabel", wxStaticText )->SetLabel( label );
  Init( items, wildcard );
}

MultiSelectDlg::MultiSelectDlg( wxWindow* parent, const wxArrayString& items, bool selectall, const wxString& label, const wxString& title ) {
  wxXmlResource* xml_res = wxXmlResource::Get();
  wxString resPath = ConfigManager::GetDataFolder() + _T( "/配置项目文件集.xrc" );
  if( !xml_res->Load( resPath ) )  {
    xml_File_lock = false;
    Manager::Get()->GetLogManager()->LogInf( F( _T( "文件丢失: %s " ), resPath.wx_str() ) );
    return;
  }
  if( !xml_res->LoadObject( this, parent, _T( "dlgGenericMultiSelect" ), _T( "wxScrollingDialog" ) ) ) {
    xml_File_lock = false;
    Manager::Get()->GetLogManager()->LogInf( _T( "资源丢失" ) );
    return;
  }
  xml_File_lock = true;
  XRCCTRL( *this, "wxID_OK", wxButton )->SetDefault();
  SetTitle( title );
  XRCCTRL( *this, "lblLabel", wxStaticText )->SetLabel( label );
  Init( items, selectall ? _T( "*" ) : _T( "" ) );
}

MultiSelectDlg::~MultiSelectDlg() {
}

void MultiSelectDlg::Init( const wxArrayString& items, const wxString& wildcard ) {
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < items.GetCount(); ++i ) {
    lst->Append( items[i] );
  }
  SelectWildCard( wildcard );
}

void MultiSelectDlg::UpdateStatus() {
  int count = 0;
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    if( lst->IsChecked( i ) ) {
      ++count;
    }
  }
  wxString msg;
  msg << _T( "已选: " ) << F( _T( "%d" ), count );
  XRCCTRL( *this, "lblStatus", wxStaticText )->SetLabel( msg );
}

wxArrayString MultiSelectDlg::GetSelectedStrings() const {
  wxArrayString ret;
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    if( lst->IsChecked( i ) ) {
      ret.Add( lst->GetString( i ) );
    }
  }
  return ret;
}

wxArrayInt MultiSelectDlg::GetSelectedIndices() const {
  wxArrayInt ret;
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    if( lst->IsChecked( i ) ) {
      ret.Add( i );
    }
  }
  return ret;
}

void MultiSelectDlg::SelectWildCard( const wxString& wild, bool select, bool clearOld ) {
  if( wild.IsEmpty() ) {
    return;
  }
  wxArrayString wilds = GetArrayFromString( wild, _T( ";" ) );
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    if( clearOld || !lst->IsChecked( i ) ) {
      wxString entry = lst->GetString( i ).Lower();
      bool MatchesWildCard = false;
      for( unsigned int x = 0; x < wilds.GetCount(); ++x ) {
        if( entry.Matches( wilds[x].Lower() ) ) {
          lst->Check( i, select );
          MatchesWildCard = true;
          break;
        }
      }
      if( !MatchesWildCard && clearOld && lst->IsChecked( i ) ) {
        lst->Check( i, false );
      }
    }
  }
  UpdateStatus();
}

void MultiSelectDlg::OnWildcard( M_Code_unused wxCommandEvent& event ) {
  wxString wild = cbGetTextFromUser( _T( "输入选择通配符\n(e.g. \"dlg*.cpp\" "
                                         "would select all files starting with \"dlg\" and "
                                         "ending in \".cpp\")\nSeparate multiple masks with \";\":" ),
                                     _T( "Wildcard selection" ) );
  if( wild.IsEmpty() ) {
    return;
  }
  bool ask_clear = false;
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    if( lst->IsChecked( i ) ) {
      ask_clear = true;
      break;
    }
  }
  bool clear = false;
  if( ask_clear ) {
    clear = msging( _T( "是否清除以前的选择?" ), _T( "Question" ), wxICON_QUESTION | wxYES_NO, this ) == wxID_YES;
  }
  SelectWildCard( wild, true, clear );
}

void MultiSelectDlg::OnItemToggle( M_Code_unused wxCommandEvent& event ) {
  UpdateStatus();
}

void MultiSelectDlg::OnToggle( M_Code_unused wxCommandEvent& event ) {
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    lst->Check( i, !lst->IsChecked( i ) );
  }
  UpdateStatus();
}

void MultiSelectDlg::OnSelectAll( M_Code_unused wxCommandEvent& event ) {
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    lst->Check( i, true );
  }
  UpdateStatus();
}

void MultiSelectDlg::OnDeselectAll( M_Code_unused wxCommandEvent& event ) {
  wxCheckListBox* lst = XRCCTRL( *this, "lstItems", wxCheckListBox );
  for( size_t i = 0; i < lst->GetCount(); ++i ) {
    lst->Check( i, false );
  }
  UpdateStatus();
}
